<?php
namespace App\Config;

class Request
{
    /**
     * 请求header参数
     *
     * @var array
     */
    private $headerParams = [];
    /**
     * 请求server参数
     *
     * @var array
     */
    private $serverParams = [];
    /**
     * 请求所有参数
     *
     * @var array
     */
    private $requestParams = [];
    /**
     *请求GET参数
     *
     * @var array
     */
    private $getParams = [];
    /**
     * 请求POST参数
     *
     * @var array
     */
    private $postParams = [];
    /**
     * 请求方法
     *
     * @var string
     */
    private $method = '';
    /**
     * cookie
     *
     * @var array
     */
    private $cookie = [];
    /**
     * file
     *
     * @var array
     */
    private $file = [];
    /**
     * 服务IP
     *
     * @var string
     */
    private $serverIp = '';
    /**
     *客户端IP
     *
     * @var string
     */
    private $clientIp = '';
    /**
     * 请求开始时间
     *
     * @var int
     */
    private $beginTime = 0;
    /**
     * 请求结束时间
     *
     * @var int
     */
    private $endTime = 0;
    /**
     * 请求耗时时间
     *
     * @var int
     */
    private $consumeTime = 0;
    /**
     * 请求身份ID
     *
     * @var string
     */
    private $requestId = '';

    /**
     * @return int
     */
    public function __construct ()
    {
        $this->serverParams  = $_SERVER;
        $this->method        = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'get';
        $this->serverIp      = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
        $this->clientIp      = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '';
        $this->beginTime     = isset($_SERVER['REQUEST_TIME_FLOAT']) ? $_SERVER['REQUEST_TIME_FLOAT'] : microtime(true);
        $this->requestParams = $_REQUEST;
        $this->getParams     = $_GET;
        $this->postParams    = $_POST;
    }

    /**
     * 魔术方法__get
     *
     * @param string $name 属性名称
     *
     * @return mixed
     */
    public function __get ($name = '')
    {
        return $this->$name;
    }

    /**
     * 魔术方法__set
     *
     * @param string $name  属性名称
     * @param string $value 属性值
     */
    public function __set ($name = '', $value = '')
    {
        $this->$name = $value;
    }

    /**
     * 获取GET参数
     *
     * @param string $key        参数名
     * @param string $default    默认值
     * @param bool   $checkEmpty 值为空时是否返回默认值，默认true
     *
     * @return string
     */
    public function get ($key = '', $default = '', $checkEmpty = true)
    {
        if (!isset($this->getParams[$key]))
        {
            return '';
        }
        if (empty($this->getParams[$key] && $checkEmpty))
        {
            return $default;
        }
        return htmlspecialchars($this->getParams[$key]);
    }

    /**
     * 获取POST参数
     *
     * @param string $key        参数名
     * @param string $default    默认值
     * @param bool   $checkEmpty 值为空时是否返回默认值，默认true
     *
     * @return string
     */
    public function post ($key = '', $default = '', $checkEmpty = true)
    {
        if (!isset($this->postParams[$key]))
        {
            return '';
        }
        if (empty($this->postParams[$key]) && $checkEmpty)
        {
            return $default;
        }
        return htmlspecialchars($this->postParams[$key]);
    }

    /**
     * 获取REQUEST参数
     *
     * @param string $key        参数名
     * @param string $default    默认值
     * @param bool   $checkEmpty 值为空是否返回默认值，默认为true
     *
     * @return string
     */
    public function request ($key = '', $default = '', $checkEmpty = true)
    {
        if (!isset($this->requestParams[$key]))
        {
            return '';
        }
        if (empty($this->getParams[$key]) && $checkEmpty)
        {
            return $default;
        }
        return htmlspecialchars($this->requestParams[$key]);
    }

    /**
     * 获取SERVER参数
     *
     * @param string $key 参数名
     *
     * @return mixed|string
     */
    public function server ($key = '')
    {
        if (isset($this->serverParams[$key]))
        {
            return $this->serverParams[$key];
        }
        return '';
    }

    /**
     * 获取所有参数
     *
     * @return array
     */
    public function all ()
    {
        $res = array_merge($this->getParams, $this->postParams);
        foreach ($res as &$re)
        {
            $re = htmlspecialchars($re);
        }
        return $res;
    }

    /**
     * 参数验证
     *
     * 支持必传参数验证，参数长度验证，参数类型验证
     *
     * @param string $paramName 参数名
     * @param string $rule      规则
     * @param int    $length
     *
     * @throws \Exception
     */
    public function check ($paramName = '', $rule = '', $length = 0)
    {
        if (!is_int($length))
        {
            throw new \Exception('length type is not int', 400);
        }
        if ($rule === 'require')
        {
            if (!empty($this->request($paramName)))
            {
                return;
            }
            throw new \Exception("param {$paramName}", 404);
        }
        if ($rule === 'length')
        {
            if (strlen($this->request($paramName)) === $length)
            {
                return;
            }
            throw new \Exception("param {$paramName} length is not {$length}", 400);
        }

        if ($rule === 'number')
        {
            if (is_numeric($this->request($paramName)))
            {
                return;
            }
            throw new \Exception("{$paramName} type is not number", 400);
        }
    }
}
